`timescale 1ns / 1ps
//////////////////////////////////////////////////////////////////////////////////
// Company: 
// Engineer: 
// 
// Create Date: 03/07/2015 03:18:08 PM
// Design Name: 
// Module Name: motor_driver
// Project Name: 
// Target Devices: 
// Tool Versions: 
// Description: 
// 
// Dependencies: 
// 
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
// 
//////////////////////////////////////////////////////////////////////////////////


module motor_driver(
    input sysclk,
    input sysreset_n,
    input direction,
    input enable,
    output div_clk,
    output reg [5:0] motor_out
);
    
parameter [2:0] OFF     = 3'd0,
                STEP1   = 3'd1,
                STEP2   = 3'd2,
                STEP3   = 3'd3,
                STEP4   = 3'd4,
                STEP5   = 3'd5,
                STEP6   = 3'd6;

parameter [1:0] PU_ON   = 2'b11,
                PD_ON   = 2'b10,
                H_OFF   = 2'b00;

parameter CLOCKWISE     = 1'b0;

parameter [31:0] CLOCK_DIVIDER = 32'd10_000_000;

reg [2:0] state, next_state;
reg [31:0] div_counter;
reg i_div_clk;

assign div_clk = i_div_clk;

always @(posedge sysclk) begin
    if (!sysreset_n) begin
        div_counter <= 32'h0;
        i_div_clk   <= 1'b0;
    end
    else begin
        if (div_counter < (CLOCK_DIVIDER - 1'b1)) begin
            i_div_clk   <= 1'b0;
            div_counter <= div_counter + 1'b1;
        end
        else begin
            i_div_clk   <= 1'b1;
            div_counter <= 32'h0;
        end
    end
end

always @(posedge i_div_clk) begin
    if (!sysreset_n) begin
        state <= OFF;
    end
    else begin
        state <= next_state;
    end
end


always @(*) begin
    case(state)
        OFF     : begin
            if (enable) begin
                if (direction == CLOCKWISE) begin
                    next_state = STEP1; 
                end
                else begin
                    next_state = STEP6;
                end
            end
            else begin
                next_state = OFF;
            end
        end

        STEP1   : begin
            if (enable) begin
                if (direction == CLOCKWISE) begin
                    next_state = STEP2; 
                end
                else begin
                    next_state = STEP6;
                end
            end
            else begin
                next_state = OFF;
            end
        end

        STEP2   : begin
            if (enable) begin
                if (direction == CLOCKWISE) begin
                    next_state = STEP3; 
                end
                else begin
                    next_state = STEP1;
                end
            end
            else begin
                next_state = OFF;
            end
        end

        STEP3   : begin
            if (enable) begin
                if (direction == CLOCKWISE) begin
                    next_state = STEP4; 
                end
                else begin
                    next_state = STEP2;
                end
            end
            else begin
                next_state = OFF;
            end
        end

        STEP4   : begin
            if (enable) begin
                if (direction == CLOCKWISE) begin
                    next_state = STEP5; 
                end
                else begin
                    next_state = STEP3;
                end
            end
            else begin
                next_state = OFF;
            end
        end

        STEP5   : begin
            if (enable) begin
                if (direction == CLOCKWISE) begin
                    next_state = STEP6; 
                end
                else begin
                    next_state = STEP4;
                end
            end
            else begin
                next_state = OFF;
            end
        end

        STEP6   : begin
            if (enable) begin
                if (direction == CLOCKWISE) begin
                    next_state = STEP1; 
                end
                else begin
                    next_state = STEP5;
                end
            end
            else begin
                next_state = OFF;
            end
        end
        
        default : begin
            next_state = OFF;
        end
    endcase
end

always @(*) begin
    case(state)
        OFF     : begin
            motor_out = {H_OFF, H_OFF, H_OFF};
        end

        STEP1   : begin
            motor_out = {PD_ON, PD_ON, PU_ON};
        end

        STEP2   : begin
            motor_out = {PD_ON, PU_ON, PU_ON};
        end

        STEP3   : begin
            motor_out = {PD_ON, PU_ON, PD_ON};
        end

        STEP4   : begin
            motor_out = {PU_ON, PU_ON, PD_ON};
        end

        STEP5   : begin
            motor_out = {PU_ON, PD_ON, PD_ON};
        end

        STEP6   : begin
            motor_out = {PU_ON, PD_ON, PU_ON};
        end

        default : begin
            motor_out = {H_OFF, H_OFF, H_OFF};
        end
    endcase
end
    
endmodule
